// 讨饭合约测试脚本
// test-begging.js

const hre = require("hardhat");

async function main() {
    console.log("🧪 开始测试讨饭合约...");

    // 获取测试账户
    const [owner, donor1, donor2, donor3] = await hre.ethers.getSigners();

    console.log("测试账户:");
    console.log("  所有者:", owner.address);
    console.log("  捐赠者1:", donor1.address);
    console.log("  捐赠者2:", donor2.address);
    console.log("  捐赠者3:", donor3.address);

    // 部署测试合约
    console.log("\n🚀 部署测试合约...");
    const BeggingContract = await hre.ethers.getContractFactory("BeggingContract");
    const beggingContract = await BeggingContract.connect(owner).deploy(
        "测试讨饭原因",
        hre.ethers.utils.parseEther("1.0"), // 目标 1 ETH
        hre.ethers.utils.parseEther("0.01"), // 最低 0.01 ETH
        1 // 1天
    );
    await beggingContract.deployed();
    console.log("✅ 合约部署完成:", beggingContract.address);

    try {
        // 测试 1: 初始状态检查
        console.log("\n📋 测试 1: 初始状态检查");
        const initialOwner = await beggingContract.owner();
        const initialBalance = await beggingContract.getContractBalance();
        const totalDonations = await beggingContract.totalDonations();

        console.log("  合约所有者:", initialOwner);
        console.log("  合约余额:", hre.ethers.utils.formatEther(initialBalance), "ETH");
        console.log("  总捐赠金额:", hre.ethers.utils.formatEther(totalDonations), "ETH");

        // 测试 2: 捐赠功能
        console.log("\n💰 测试 2: 捐赠功能");

        // 捐赠者1捐赠 0.1 ETH
        console.log("  捐赠者1 捐赠 0.1 ETH...");
        const donation1 = await beggingContract.connect(donor1).donate("第一笔捐赠", {
            value: hre.ethers.utils.parseEther("0.1")
        });
        await donation1.wait();
        console.log("  ✅ 捐赠1完成");

        // 捐赠者2捐赠 0.2 ETH
        console.log("  捐赠者2 捐赠 0.2 ETH...");
        const donation2 = await beggingContract.connect(donor2).donate("第二笔捐赠", {
            value: hre.ethers.utils.parseEther("0.2")
        });
        await donation2.wait();
        console.log("  ✅ 捐赠2完成");

        // 捐赠者3捐赠 0.05 ETH (两次)
        console.log("  捐赠者3 捐赠 0.05 ETH (第一次)...");
        const donation3a = await beggingContract.connect(donor3).donate("第三笔捐赠", {
            value: hre.ethers.utils.parseEther("0.05")
        });
        await donation3a.wait();

        console.log("  捐赠者3 捐赠 0.05 ETH (第二次)...");
        const donation3b = await beggingContract.connect(donor3).donate("第四笔捐赠", {
            value: hre.ethers.utils.parseEther("0.05")
        });
        await donation3b.wait();
        console.log("  ✅ 捐赠3完成");

        // 测试 3: 查询捐赠记录
        console.log("\n🔍 测试 3: 查询捐赠记录");
        const donor1Amount = await beggingContract.getDonation(donor1.address);
        const donor2Amount = await beggingContract.getDonation(donor2.address);
        const donor3Amount = await beggingContract.getDonation(donor3.address);

        console.log("  捐赠者1捐赠金额:", hre.ethers.utils.formatEther(donor1Amount), "ETH");
        console.log("  捐赠者2捐赠金额:", hre.ethers.utils.formatEther(donor2Amount), "ETH");
        console.log("  捐赠者3捐赠金额:", hre.ethers.utils.formatEther(donor3Amount), "ETH");

        // 测试 4: 合约状态检查
        console.log("\n📊 测试 4: 合约状态检查");
        const contractBalance = await beggingContract.getContractBalance();
        const stats = await beggingContract.getDonationStats();

        console.log("  合约余额:", hre.ethers.utils.formatEther(contractBalance), "ETH");
        console.log("  总捐赠金额:", hre.ethers.utils.formatEther(stats.totalAmount), "ETH");
        console.log("  捐赠者数量:", stats.donorCount.toString());
        console.log("  目标完成进度:", stats.progress.toString(), "%");

        // 测试 5: 排行榜功能
        console.log("\n🏆 测试 5: 排行榜功能");
        const [topDonors, topAmounts] = await beggingContract.getTop3Donors();

        for (let i = 0; i < topDonors.length && topDonors[i] !== hre.ethers.constants.AddressZero; i++) {
            console.log(`  第${i + 1}名:`, topDonors[i], "-", hre.ethers.utils.formatEther(topAmounts[i]), "ETH");
        }

        // 测试 6: 事件监听
        console.log("\n📡 测试 6: 检查事件");
        const donationFilter = beggingContract.filters.Donation();
        const donationEvents = await beggingContract.queryFilter(donationFilter);

        console.log("  捐赠事件数量:", donationEvents.length);
        donationEvents.forEach((event, index) => {
            console.log(`  事件${index + 1}:`, {
                donor: event.args.donor,
                amount: hre.ethers.utils.formatEther(event.args.amount),
                message: event.args.message
            });
        });

        // 测试 7: 提取功能 (仅所有者)
        console.log("\n💸 测试 7: 提取功能");
        const balanceBeforeWithdraw = await owner.getBalance();
        console.log("  所有者提取前余额:", hre.ethers.utils.formatEther(balanceBeforeWithdraw), "ETH");

        const withdrawTx = await beggingContract.connect(owner).withdraw(hre.ethers.utils.parseEther("0.2"));
        await withdrawTx.wait();

        const balanceAfterWithdraw = await owner.getBalance();
        console.log("  所有者提取后余额:", hre.ethers.utils.formatEther(balanceAfterWithdraw), "ETH");

        const finalContractBalance = await beggingContract.getContractBalance();
        console.log("  合约剩余余额:", hre.ethers.utils.formatEther(finalContractBalance), "ETH");

        // 测试 8: 权限检查 (非所有者尝试提取)
        console.log("\n🔒 测试 8: 权限检查");
        try {
            await beggingContract.connect(donor1).withdraw(hre.ethers.utils.parseEther("0.1"));
            console.log("  ❌ 权限检查失败: 非所有者成功提取了资金");
        } catch (error) {
            console.log("  ✅ 权限检查通过: 非所有者无法提取资金");
        }

        // 测试 9: 最低捐赠金额检查
        console.log("\n💎 测试 9: 最低捐赠金额检查");
        try {
            await beggingContract.connect(donor1).donate("小额捐赠", {
                value: hre.ethers.utils.parseEther("0.001") // 低于最低要求
            });
            console.log("  ❌ 最低金额检查失败: 接受了过小的捐赠");
        } catch (error) {
            console.log("  ✅ 最低金额检查通过: 拒绝了过小的捐赠");
        }

        // 测试 10: 直接转账测试 (receive函数)
        console.log("\n📤 测试 10: 直接转账测试");
        const directTx = await donor1.sendTransaction({
            to: beggingContract.address,
            value: hre.ethers.utils.parseEther("0.05")
        });
        await directTx.wait();

        const updatedDonor1Amount = await beggingContract.getDonation(donor1.address);
        console.log("  直接转账后捐赠者1总金额:", hre.ethers.utils.formatEther(updatedDonor1Amount), "ETH");

        // 最终状态报告
        console.log("\n📈 最终状态报告");
        const finalStats = await beggingContract.getDonationStats();
        console.log("  最终合约余额:", hre.ethers.utils.formatEther(await beggingContract.getContractBalance()), "ETH");
        console.log("  最终总捐赠:", hre.ethers.utils.formatEther(finalStats.totalAmount), "ETH");
        console.log("  最终捐赠者数:", finalStats.donorCount.toString());
        console.log("  最终完成进度:", finalStats.progress.toString(), "%");

        console.log("\n🎉 所有测试完成!");

    } catch (error) {
        console.error("\n❌ 测试过程中出现错误:", error);
        process.exit(1);
    }
}

// 运行测试
main().catch((error) => {
    console.error("\n💥 测试脚本执行出错:", error);
    process.exitCode = 1;
});
